package cn.fintecher.gis.web;

import cn.fintecher.gis.entity.*;
import cn.fintecher.gis.exception.BadRequestException;
import cn.fintecher.gis.model.request.RoleInfoRequest;
import cn.fintecher.gis.model.response.ResourceResponse;
import cn.fintecher.gis.model.response.RoleAndResourceResponse;
import cn.fintecher.gis.model.response.RoleInfoResponse;
import cn.fintecher.gis.model.response.RoleResourceRequest;
import cn.fintecher.gis.respository.OperatorRepository;
import cn.fintecher.gis.respository.ResourceRepository;
import cn.fintecher.gis.respository.RoleInfoRepository;
import cn.fintecher.gis.service.LogInfoService;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.querydsl.core.BooleanBuilder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/api/roleInfo")
@Api(value = "角色管理", description = "角色管理")
public class RoleInfoController {

    private final Logger log = LoggerFactory.getLogger(RoleInfoController.class);

    @Autowired
    private RoleInfoRepository roleInfoRepository;

    @Autowired
    private ResourceRepository resourceRepository;

    @Autowired
    private OperatorRepository operatorRepository;

    @Autowired
    private LogInfoService logInfoService;


    @GetMapping("/queryRoleInfoList")
    @ApiOperation(value = "查询角色列表信息", notes = "查询角色列表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", dataType = "int", paramType = "query",
                    value = "页数 (0..N)"),
            @ApiImplicitParam(name = "size", dataType = "int", paramType = "query",
                    value = "每页大小."),
            @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query",
                    value = "依据什么排序: 属性名(,asc|desc). ")
    })
    public ResponseEntity<Page<RoleInfoResponse>> queryRoleInfoList(RoleInfoRequest request, Pageable pageable) {
        BooleanBuilder builder = new BooleanBuilder();
        QRoleInfo qRoleInfo = QRoleInfo.roleInfo;
        builder.and(qRoleInfo.id.ne("111111111"));
        if (request.getRoleName() != null && !request.getRoleName().isEmpty()) {
            builder.and(qRoleInfo.roleName.like("%".concat(request.getRoleName()).concat("%")));
        }
        if (Objects.nonNull(request.getRoleStatus())) {
            builder.and(qRoleInfo.roleStatus.eq(request.getRoleStatus()));
        }
        Page<RoleInfo> roleInfoPage = roleInfoRepository.findAll(builder, pageable);
        Page<RoleInfoResponse> page = roleInfoPage.map(roleInfo ->{
            RoleInfoResponse response = new RoleInfoResponse();
            BeanUtils.copyProperties(roleInfo,response);
            List<String> list = roleInfo.getResources().stream().map(e->e.getId()).collect(Collectors.toList());
            response.setResourceIds(list);
            return response;
        });
        return ResponseEntity.ok().body(page);
    }

    @GetMapping("/getRoleInfoList")
    @ApiOperation(value = "查询角色列表信息", notes = "查询角色列表信息")
    public ResponseEntity<List<RoleInfoResponse>> getRoleInfoList() {
        BooleanBuilder builder = new BooleanBuilder();
        QRoleInfo qRoleInfo = QRoleInfo.roleInfo;
        builder.and(qRoleInfo.id.ne("111111111"));
        Iterator<RoleInfo> infoIterator = roleInfoRepository.findAll(builder).iterator();
        List<RoleInfo> roleInfoList = Lists.newArrayList(infoIterator);
        List<RoleInfoResponse> roleInfoResponses = new ArrayList<>();
        for(RoleInfo roleInfo : roleInfoList){
            RoleInfoResponse response = new RoleInfoResponse();
            BeanUtils.copyProperties(roleInfo,response);
            List<String> list = roleInfo.getResources().stream().map(e->e.getId()).collect(Collectors.toList());
            response.setResourceIds(list);
            roleInfoResponses.add(response);
        }
        return ResponseEntity.ok().body(roleInfoResponses);
    }

    @GetMapping("/getRoleInfoById")
    @ApiOperation(value="根据角色id查询角色信息",notes="根据角色id查询角色信息")
    public ResponseEntity<RoleAndResourceResponse> getRoleInfoById(@RequestParam("roleId") String roleId) {
        RoleAndResourceResponse roleAndResourceResponse = new RoleAndResourceResponse();
        Optional<RoleInfo> roleOptional = roleInfoRepository.findById(roleId);
        roleOptional.orElseThrow(() -> new BadRequestException(RoleInfo.class.getSimpleName(), "role.is.not.exist"));
        RoleInfo roleInfo = roleOptional.get();
        Set<Resource> set = roleInfo.getResources();
        BeanUtils.copyProperties(roleInfo, roleAndResourceResponse);
        List<ResourceResponse> responses = new ArrayList<>();
        for (Resource resource : set) {
            ResourceResponse response = new ResourceResponse();
            BeanUtils.copyProperties(resource, response);
            if (Objects.nonNull(resource.getParent())) {
                response.setParentId(resource.getParent().getId());
            }
            responses.add(response);
        }
        roleAndResourceResponse.setResources(responses);
        return ResponseEntity.ok().body(roleAndResourceResponse);
    }

    @PostMapping("/createRoleInfo")
    @ApiOperation(value = "角色的创建", notes = "角色的创建")
    public ResponseEntity<Void> createRoleInfo(@RequestBody RoleInfoRequest request) {
        RoleInfo roleInfo = new RoleInfo();
        roleInfo.setRoleName(request.getRoleName());
        roleInfo.setRoleStatus(request.getRoleStatus());
        roleInfoRepository.save(roleInfo);
        return ResponseEntity.ok().body(null);
    }


    @PostMapping("/updateRoleInfo")
    @ApiOperation(value = "角色的修改", notes = "角色的修改")
    public ResponseEntity<Void> updateRoleInfo(@RequestBody RoleInfoRequest request) {
        Optional<RoleInfo> roleOptional = roleInfoRepository.findById(request.getId());
        roleOptional.orElseThrow(() -> new BadRequestException(RoleInfo.class.getSimpleName(), "role.is.not.exist"));
        RoleInfo roleInfo = roleOptional.get();
        roleInfo.setRoleStatus(request.getRoleStatus());
        roleInfo.setRoleName(request.getRoleName());
        roleInfoRepository.save(roleInfo);
        return ResponseEntity.ok().body(null);
    }

    @PostMapping("/roleAttachResource")
    @ApiOperation(value = "角色赋权限", notes = "角色赋权限")
    public ResponseEntity<Void> roleAttachResource(@RequestBody RoleResourceRequest request) {
        Optional<RoleInfo> roleOptional = roleInfoRepository.findById(request.getRoleId());
        roleOptional.orElseThrow(() -> new BadRequestException(RoleInfo.class.getSimpleName(), "role.is.not.exist"));
        Iterable<Resource> resourceRepositoryAll = resourceRepository.findAll(QResource.resource.id.in(request.getResourceIds()));
        RoleInfo roleInfo = roleOptional.get();
        roleInfo.setResources(Sets.newHashSet(resourceRepositoryAll));
        roleInfoRepository.saveAndFlush(roleInfo);
        return ResponseEntity.ok().body(null);
    }

    @DeleteMapping("/deleteRoleInfoById/{id}")
    @ApiOperation(value = "根据id删除角色信息", notes = "根据id删除角色信息")
    public ResponseEntity<Void> roleAttachResource(@PathVariable String id) {
        Optional<RoleInfo> roleOptional = roleInfoRepository.findById(id);
        roleOptional.orElseThrow(() -> new BadRequestException(RoleInfo.class.getSimpleName(), "role.is.not.exist"));
        RoleInfo roleInfo = roleOptional.get();
        Iterator<Operator> operatorIterator = operatorRepository.findAll(QOperator.operator.roles.contains(roleInfo)).iterator();
        if(operatorIterator.hasNext()){
            throw new BadRequestException("roles.have.bound.users","roles.have.bound.users");
        }
        logInfoService.addLog("RoleInfoController", "deleteRoleInfoById",
                "id=" + id, "删除的角色是:" + roleInfo.getRoleName());
        roleInfoRepository.delete(roleInfo);
        return ResponseEntity.ok().body(null);
    }

    @GetMapping("/getResourceList")
    @ApiOperation(value = "查询所有的资源信息",notes = "查询所有的资源信息")
    public ResponseEntity<List<ResourceResponse>> getResourceList(){
        List<ResourceResponse> resourceResponses = new ArrayList<>();
        List<Resource> list = resourceRepository.findAll();
        for(Resource resource : list){
            ResourceResponse response = new ResourceResponse();
            BeanUtils.copyProperties(resource,response);
            if (Objects.nonNull(resource.getParent())) {
                response.setParentId(resource.getParent().getId());
            }
            resourceResponses.add(response);
        }
        return ResponseEntity.ok().body(resourceResponses);
    }
}
